﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using JEng_Mark_1.Interfaces;
using JEng_Mark_1.Managers;
using Microsoft.Xna.Framework.Graphics;
using JEng_Mark_1.GameComponents;

namespace JEng_Mark_1.SceneObject
{
    public class JSceneObject : IJEngSceneObject
    {
        public VertexPositionColor[] points = new VertexPositionColor[8];
        public int[] index = new int[24];

        private bool _readyToRender = true;//false;
        /// <summary>
        /// Is this object ready to be rendered?
        /// </summary>
        public bool ReadyToRender { get { return _readyToRender; } set { _readyToRender = value; } }

        private BoundingBox _boundingBox;

        /// <summary>
        /// Get / set the bounding box of this object, used for culling
        /// </summary>
        public BoundingBox BoundingBox { get { return _boundingBox; } set { _boundingBox = value; } }

        private JMaterial _material;

        /// <summary>
        /// Get / set the material for this scene object
        /// </summary>
        public JMaterial Material { get { return _material; } set { _material = value; } }

        private string _modelName;

        /// <summary>
        /// Get / set the name of the model associated with this scene object
        /// </summary>
        public string ModelName { get { return _modelName; } set { _modelName = value; } }

        private Vector3 _position = Vector3.Zero;

        /// <summary>
        /// The position of this object in 3d space
        /// </summary>
        public Vector3 Position { get { return _position; } set { _position = value; } }

        private Vector3 _scale = Vector3.One;

        /// <summary>
        /// Get / Set the scaling of the object
        /// </summary>
        public Vector3 Scale { get { return _scale; } set { _scale = value; } }

        private Quaternion _rotation = Quaternion.Identity;

        /// <summary>
        /// Yay, pitch and roll of the object
        /// </summary>
        public Quaternion Rotation { get { return _rotation; } set { _rotation = value; } }

        /// <summary>
        /// Get the world matrix
        /// </summary>
        public virtual Matrix World
        {
            get
            {
                return Matrix.CreateScale(this.Scale) *
                       Matrix.CreateFromQuaternion(this.Rotation) *
                       Matrix.CreateTranslation(this.Position);
            }
        }

        /// <summary>
        /// Draw the object
        /// </summary>
        /// <param name="gameTime">Timing snapshot</param>
        public virtual void Draw(GameTime gameTime)
        {
            if (ReadyToRender)
            {
                IJEngModel model = JModelManager.GetModel(_modelName);
                if (model != null && model.ReadyToRender)
                {
                    Matrix[] transforms = new Matrix[model.BaseModel.Bones.Count];
                    model.BaseModel.CopyAbsoluteBoneTransformsTo(transforms);

                    foreach (ModelMesh mesh in model.BaseModel.Meshes)
                    {
                        foreach (BasicEffect effect in mesh.Effects)
                        {
                            effect.EnableDefaultLighting();
                            effect.PreferPerPixelLighting = true;
                            effect.World = World;
                            effect.View = JCameraManager.ActiveCamera.View;
                            effect.Projection = JCameraManager.ActiveCamera.Projection;
                        }
                        mesh.Draw();
                    }
                }
            }/*
            IJEngModel model = JModelManager.GetModel(_modelName);
            if (model != null && model.ReadyToRender)
            {
                Matrix[] transforms = new Matrix[model.BaseModel.Bones.Count];
                model.BaseModel.CopyAbsoluteBoneTransformsTo(transforms);

                foreach (ModelMesh mesh in model.BaseModel.Meshes)
                {
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;
                        effect.World = transforms[mesh.ParentBone.Index] * Matrix.Identity;

                        effect.View = JCameraManager.ActiveCamera.View;
                        effect.Projection = JCameraManager.ActiveCamera.Projection;
                    }
                    mesh.Draw();
                }
            }*/
        }

        /// <summary>
        /// Draw the node's bounding box
        /// </summary>
        /// <param name="gameTime">Timing snapshot</param>
        public void DrawNodesBoundingBox(GameTime gameTime)
        {
            if (ReadyToRender)
            {
                using (VertexDeclaration declaration = new VertexDeclaration(JEngineManager.Device, VertexPositionColor.VertexElements))
                {
                    JEngineManager.Device.RenderState.PointSize = 1.0f;
                    JEngineManager.Device.VertexDeclaration = declaration;

                    IJEngShader shader = JShaderManager.GetShader("BasicEffect");

                    if (shader.ReadyToRender)
                    {
                        BasicEffect effect = shader.BaseEffect as BasicEffect;
                        effect.DiffuseColor = Color.Red.ToVector3();
                        effect.View = JCameraManager.ActiveCamera.View;
                        effect.Projection = JCameraManager.ActiveCamera.Projection;
                        effect.World = World;

                        effect.Begin();

                        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                        {
                            pass.Begin();
                            JEngineManager.Device.DrawUserIndexedPrimitives<VertexPositionColor>(
                                                PrimitiveType.LineList, points,
                                                0,
                                                8,
                                                index,
                                                0,
                                                12);
                            pass.End();
                        }
                        effect.End();
                    }
                }
            }
        }
    }
}
